Software applications often need to meet certain resource constraints. For example, a given application may have a time constraint, such as calculating a return value in a set amount of time. The same application may also have to meet a memory constraint, such as using less than a set amount of random access memory to calculate the value. Network bandwidth and latency, storage capacity, and responsiveness to user commands can also impose resource constraints on software.
When developing a software application, software engineers may use a number of techniques to ensure the application meets all of the resource constraints. For example, software engineers may simply provide test cases for a wide variety of circumstances, and execute each test case to see whether the application can meet the resource constraints. However, this approach tends to yield only “pass/fail” results, and therefore may provide only limited visibility into the resource efficiency of the application.
More sophisticated tools are available for software engineers to analyze the resource consumption of an application. These tools are generally called “profilers,” and fall into two broad categories. “Event-based” profilers monitor predefined events in a software application, such as calls to routines, and provide resource consumption statistics for each event. “Statistical” profilers sample the execution of an application over a given execution, and compile statistics from the samples to provide resource consumption statistics for the sampled execution.
One type of event-based profilers are “graph” profilers, which provide resource consumption information in a “call tree.” The call tree is usually a nested list of routines, which allows a software engineer to view the progression of calls from high-level routines down to more specific routines in an application. The call tree may also provide aggregate runtimes, memory consumption, and other resource metrics for each routine.
Using a call tree, a software engineer can focus on particularly resource-intensive routines in an application. Thus, the software engineer can make changes to make the more resource-intensive routines more efficient. By improving the efficiency of the routines in an application, the software engineer can reduce the overall resource consumption of the application.
However, there are several problems that are unsolved by existing profilers. First, existing profilers tend to point software developers towards the routines in an application that use the most resources. However, these routines are not necessarily inefficient—they may be well-written but resource-intensive routines that are not susceptible to more efficient implementations. Thus, existing profilers are over inclusive in the sense that they may lead software engineers to spend effort trying to improve routines that may already be quite efficient.
Second, in a given profiled execution of an application, inefficient routines will not necessarily constitute a large percentage of the resource consumption. This is because the test case used to generate the profile may present the inefficient routines with input sizes that do not cause the inefficient routines to exhibit their inefficient behavior. Thus, an inefficient routine will consume a relatively small percentage of the resources in test case used to generate the profile, but may actually consume quite a large amount of resources under a different test case or in actual use. In this sense, existing profilers are underinclusive in that they do not lead software engineers to consider improving inefficient routines unless the test case used to generate the profile causes the inefficient routine to constitute a relatively large portion of the application's resource consumption.
Another problem with existing profilers is that inefficient routines can be “buried” in a large profile. For example, an application may run for a relatively long time, perhaps a few hours, and the entire time a profiler may be storing information about the resource consumption of the application. In order to accurately profile such a long execution, a tremendous amount of data will need to be stored during the execution. Thus, it can be difficult for a software engineer to find exactly where in the profile any inefficient routines have used too much of a particular resource.
Thus, it is desirable to provide software engineers with an enhanced profiler that identifies inefficient routines in a software application, even if the inefficient routines do not account for a large portion of the application's resource consumption.